﻿using Abp.IdentityServer4;
using Abp.Zero.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using DHJ.Cost.Authorization.Roles;
using DHJ.Cost.Authorization.Users;
using DHJ.Cost.Chat;
using DHJ.Cost.CostAccounting;
using DHJ.Cost.CostBooking;
using DHJ.Cost.Editions;
using DHJ.Cost.Excel;
using DHJ.Cost.Friendships;
using DHJ.Cost.ManHours;
using DHJ.Cost.Models;
using DHJ.Cost.MultiTenancy;
using DHJ.Cost.MultiTenancy.Accounting;
using DHJ.Cost.MultiTenancy.Payments;
using DHJ.Cost.Quality;
using DHJ.Cost.RealTimeCost;
using DHJ.Cost.Reports;
using DHJ.Cost.Storage;
using DHJ.Cost.Tasks;
using DHJ.Cost.TreeStructure;

namespace DHJ.Cost.EntityFrameworkCore
{
    public class CostDbContext : AbpZeroDbContext<Tenant, Role, User, CostDbContext>, IAbpPersistedGrantDbContext
    {
        /* Define an IDbSet for each entity of the application */

        public virtual DbSet<BinaryObject> BinaryObjects { get; set; }

        public virtual DbSet<Friendship> Friendships { get; set; }

        public virtual DbSet<ChatMessage> ChatMessages { get; set; }

        public virtual DbSet<SubscribableEdition> SubscribableEditions { get; set; }

        public virtual DbSet<SubscriptionPayment> SubscriptionPayments { get; set; }

        public virtual DbSet<Invoice> Invoices { get; set; }

        public virtual DbSet<PersistedGrantEntity> PersistedGrants { get; set; }


        //Tasks
        public virtual DbSet<Task> Tasks { get; set; }

        public virtual DbSet<Batch> Batches { get; set; }

        public virtual DbSet<AssemRel> AssemRels { get; set; }

        //ManHours
        public virtual DbSet<BatchManHour> BatchManHours { get; set; }

        // ExcelData
        public virtual DbSet<ExcelData> ExcelDatas { get; set; }
        public virtual DbSet<ExcelItemData> ExcelItemDatas { get; set; }

        //CostBooking
        public virtual DbSet<ActualCost> ActualCosts { get; set; }

        public virtual DbSet<DirectCost> DirectCosts { get; set; }

        public virtual DbSet<TreeNodeBase> TreeNodeBase { get; set; }

        public virtual DbSet<SzReport> SzReports { get; set; }
        public virtual DbSet<ChReport> ChReports { get; set; }
        public virtual DbSet<AllocRel> AllocRels { get; set; }

        public virtual DbSet<Model> Models { get; set; }

        public virtual DbSet<Launch> Launches { get; set; }

        public virtual DbSet<Pici> Pici { get; set; }

        //Quality
        public virtual DbSet<QcCard> QcCards { get; set; }
        public virtual DbSet<KitItem> KitItems { get; set; }


        // RealTimeCost
        public virtual DbSet<EstimatedCost> EstimatedCosts { get; set; }
        public virtual DbSet<EstimatedCostMessage> EstimatedCostMessages { get; set; }



        public CostDbContext(DbContextOptions<CostDbContext> options)
            : base(options)
        {
            
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<BinaryObject>(b =>
            {
                b.HasIndex(e => new { e.TenantId });
            });

            modelBuilder.Entity<ChatMessage>(b =>
            {
                b.HasIndex(e => new { e.TenantId, e.UserId, e.ReadState });
                b.HasIndex(e => new { e.TenantId, e.TargetUserId, e.ReadState });
                b.HasIndex(e => new { e.TargetTenantId, e.TargetUserId, e.ReadState });
                b.HasIndex(e => new { e.TargetTenantId, e.UserId, e.ReadState });
            });

            modelBuilder.Entity<Friendship>(b =>
            {
                b.HasIndex(e => new { e.TenantId, e.UserId });
                b.HasIndex(e => new { e.TenantId, e.FriendUserId });
                b.HasIndex(e => new { e.FriendTenantId, e.UserId });
                b.HasIndex(e => new { e.FriendTenantId, e.FriendUserId });
            });

            modelBuilder.Entity<Tenant>(b =>
            {
                b.HasIndex(e => new { e.SubscriptionEndDateUtc });
                b.HasIndex(e => new { e.CreationTime });
            });

            modelBuilder.Entity<SubscriptionPayment>(b =>
            {
                b.HasIndex(e => new { e.Status, e.CreationTime });
                b.HasIndex(e => new { PaymentId = e.ExternalPaymentId, e.Gateway });
            });

            // ExcelData
            modelBuilder.Entity<ExcelData>(b => { b.OwnsOne(e => e.Time); });
            modelBuilder.Entity<ExcelItemData>(b => { b.Ignore(e => e.Cells); });

            //ManHours
            modelBuilder.Entity<BatchManHour>(b =>
            {
                b.OwnsOne(e => e.Time);
                b.OwnsOne(e => e.Hours);
            });

            //Report
            modelBuilder.Entity<SzReport>(b => { b.OwnsOne(e => e.Time); });

            modelBuilder.Entity<ChReport>(b => { b.OwnsOne(e => e.Time); });

            //Costs
            modelBuilder.Entity<ActualCost>(b =>
            {
                b.OwnsOne(e => e.Time);
                b.OwnsOne(e => e.Subject);
                b.OwnsOne(e => e.Detail);
            });

            modelBuilder.Entity<AllocRel>(b =>
            {
                b.Property(e => e.Ratio).HasColumnType("decimal(18, 8)");
            });

            modelBuilder.Entity<DirectCost>(b => { b.OwnsOne(e => e.Batches); });

            modelBuilder.ConfigurePersistedGrantEntity();
        }
    }
}
